package tomkitty.server;

import tomkitty.turdlet.*;
import tomkitty.util.*;
import java.util.*;
import java.io.*;

/**
 *
 * Main HTTP server class. Entry point of the server.
 *
 * Based on the example:
 * http://java.sun.com/developer/technicalArticles/Networking/Webserver/
 *
 * @author alan, micha
 *
 */
public class Main {
    
		public static final String version = "0.1 alpha";
		private static Configuration conf;
		private Hashtable<Object, Object> registeredData;
		private static AppLoader appLoader;

		private void printHelp() {
			p("");
			p("Usage: java -jar tomkitty.jar [OPTIONS]");
			p("");
			p("OPTIONS are as follows:");
			p("    -h               this help message");
			p("    -o [key=value]   set a config option");
			p("    -s               show config options and quit");
			p("");
		}

		private void printConf(Configuration conf) {
			Enumeration e = conf.keys();

			p("");
			while(e.hasMoreElements()) {
				String key = (String) e.nextElement();
				Vector<String> v = conf.getAll(key);
				System.out.printf("%-45s %s\n", key + "=[" + v.get(1) + "]",
						"default=\"" + v.get(0) + "\"");
				p(v.get(2));
				p("");
			}
		}

		public static AppLoader getAppLoader() {
			return appLoader;
		}

		public void scanClassPath() {
			String appDirs;
			appDirs = conf.get("classpath") + File.pathSeparator + 
				System.getenv("CLASSPATH");
				
			String[] dirs = appDirs.split(File.pathSeparator);

			for (int i = 0; i < dirs.length; i++) {
				if (dirs[i].length() > 0) {
					System.out.printf("Running AppLoader on '"+dirs[i]+"'...");
					if (appLoader.scanDir(dirs[i])) {
						p("OK");
					} else {
						p("FAIL");
					}
				}
			}
		}
					
    /** Creates a new instance of Main */
    public Main(String[] argv) {
			p("tomkitty v" + version + " - it puts the turdlet in the kitty");
			p("");

			conf = new Configuration();
			appLoader = new AppLoader();
			registeredData = new Hashtable<Object, Object>();

			conf.setAll("port", "8080", "integer",
					"	Port on which tomkitty will accept incoming connections.");
			conf.setAll("minthreads", "10", "integer",
					"	Minimum number of threads in thread pool when idle.");
			conf.setAll("maxthreads", "100", "integer",
					"	Maximum total number of threads at any time.");
			conf.setAll("default_app", "hellokitty", "myapp",
					"	Default app to load.");
			conf.setAll("default_turdlet", "Index", "class name",
					"	Default turdlet class to load.");
			conf.setAll("docroot", null, "directory path",
					"	Root of the webserver directory heirarchy from which files will\n" +
					"	be served.");
			conf.setAll("default_file", "index.html", "filename",
					"	Default file name to serve when only a directory is specified.");
			conf.setAll("list_hidden_files", "false", "true/false",
					"	Show hidden files when listing the contents of directories.");
			conf.setAll("classpath", null, "path" + File.pathSeparator + "path" +
					File.pathSeparator + "...",
					"	Directories containing webapp jar files.");

			//
			// parse command line args
			//

			for(int i = 0; i < argv.length; i++) {
				String allowedOptions = "hos";
				if (argv[i].charAt(0) != '-' || argv[i].length() != 2 ||
						allowedOptions.indexOf(argv[i].charAt(1)) < 0) {
					p("tomkitty: bad option: " + argv[i]);
					printHelp();
					System.exit(1);
				}
				switch(argv[i].charAt(1)) {
					case 'h':
						printHelp();
						System.exit(0);
						break;
					case 'o':
						String arg;
						if (argv.length > i + 1) {
							arg = argv[i + 1];
							int j = arg.indexOf('=');
							if (j > 0 && arg.length() > j + 1) {
								conf.set(arg.substring(0,j), arg.substring(j + 1));
							} else {
								p("tomkitty: bad argument: '" + arg + "' (expected KEY=VALUE)");
								printHelp();
								System.exit(1);
							}
							i++;
						} else {
							p("tomkitty: missing parameter: " + argv[i]);
							printHelp();
							System.exit(1);
						}
						break;
					case 's':
						printConf(conf);
						System.exit(0);
						break;
				}
			}

			if (conf.get("docroot") == null) {
				p("tomkitty: no 'docroot' option specified!");
				printHelp();
				System.exit(1);
			}

			// Load app classes
			scanClassPath();

			Server ss = new Server(toInt(conf.get("port")), 
					toInt(conf.get("minthreads")), toInt(conf.get("maxthreads")));
    }

		private int toInt(String s) {
			return new Integer(s).intValue();
		}

		public static Configuration getConfig() {
			return conf;
		}

    /**
     * Convenience stdout wrapper
     * @param s The String to print to stdout
     */
    protected static void p(String s) {
        System.out.println(s);
    }
    
    /**
     * Instantiate and kick things off.
     * @param argv the command line arguments
     */
    public static void main(String[] argv) {
        new Main(argv);
    }
}
